//
// Created by Administrator on 2023/9/3.
//

#include <stdlib.h>
#include "my_gui.h"
#include "../lvgl.h."
#include "debug.h"

#if 0
void my_gui(void)

#include "../Middlewares/lvgl/demos/benchmark/lv_demo_benchmark.h"
#include "../Middlewares/lvgl/demos/benchmark/lv_demo_benchmark.h"
{
//    lv_group_t *group = lv_group_create();	//创建一个组
//    lv_group_set_default(group);			//设置为默认组
//    lv_indev_set_group(indev_keypad, group);//将组和输入设备相关联

    lv_obj_t *switch_obj1 = lv_switch_create(lv_scr_act());
    lv_obj_set_size(switch_obj1, 60, 30);
    lv_obj_align(switch_obj1, LV_ALIGN_CENTER, 35, -20);

    lv_obj_t *switch_obj2 = lv_switch_create(lv_scr_act());
    lv_obj_set_size(switch_obj2, 60, 30);
    lv_obj_align(switch_obj2, LV_ALIGN_CENTER, 35, 20);

    lv_obj_t *switch_obj3 = lv_switch_create(lv_scr_act());
    lv_obj_set_size(switch_obj3, 60, 30);
    lv_obj_align(switch_obj3, LV_ALIGN_CENTER, 35, 60);

//    lv_obj_t *switch_obj4 = lv_switch_create(lv_scr_act());
//    lv_obj_set_size(switch_obj4, 60, 30);
//    lv_obj_align(switch_obj4, LV_ALIGN_CENTER, 35, 100);
}
#endif

#if 1

static void btn_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * btn = lv_event_get_target(e);
    if(code == LV_EVENT_CLICKED) {
        static uint8_t cnt = 0;
        cnt++;

        /*Get the first child of the button which is the label and change its text*/
        lv_obj_t * label = lv_obj_get_child(btn, 0);
        lv_label_set_text_fmt(label, "Button: %d", cnt);
    }
}

/**
 * Create a button with a label and react on click event.
 */
void my_gui(void)
{
    lv_obj_t * btn = lv_btn_create(lv_scr_act());     /*Add a button the current screen*/
    lv_obj_set_pos(btn, 10, 10);                            /*Set its position*/
    lv_obj_set_size(btn, 120, 50);                          /*Set its size*/
    lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);           /*Assign a callback to the button*/

    lv_obj_t * label = lv_label_create(btn);          /*Add a label to the button*/
    lv_label_set_text(label, "Button");                     /*Set the labels text*/
    lv_obj_center(label);
}
#endif // 1

#if 0

static const lv_font_t *font = &lv_font_montserrat_14;
static const lv_font_t *fontmin = &lv_font_montserrat_10;

LV_IMG_DECLARE(background);
//LV_IMG_DECLARE(phone);
LV_IMG_DECLARE(disc);
LV_IMG_DECLARE(pointer1);
LV_IMG_DECLARE(pointer2);
LV_IMG_DECLARE(Battery);
LV_IMG_DECLARE(wifi2);

lv_obj_t *img_background1;
lv_obj_t *img_background2;

lv_obj_t *img_disc;
lv_obj_t * img_pointer_left;
lv_obj_t * img_pointer_right;
lv_obj_t * img_power;
lv_obj_t * img_wifi2;
lv_obj_t * img_phone;
lv_obj_t * obj_date;//日期
lv_obj_t * obj_time;//时间
lv_obj_t * obj_phone_number;//电话号

static int16_t now_angle_left = 600;        //当前值，左边指针
static int16_t desire_angle_left;           //期望值，左边指针
static int16_t now_angle_right = 350;       //当前值，右边指针
static int16_t desire_angle_right;          //期望值，右边指针

//================参数设置表格=================

#define DEBUG_ANGL (0)//设置1 开始调试，表盘对应角度，设置0关闭调试，表盘对应实际表盘的值、

//调整这个表格，实现更加准确的阶梯对应
//速度映射表 速度->角度(0-3600，对应0度到360.0度)
static int mapping_points_speed[][2] = {
        {0, 600},
        {10, 760},
        {100, 2100},
        {180, 2700},
        {220, 3000},
};
//海拔映射表 海拔->角度(0-3600，对应0度到360.0度)
static int mapping_points_asl[][2] = {
        {0, 350},
        {750, 900},
        {1000, 1080},
        {1500, 1440},
        {2000, 1800},
        {3000, 2500},
        {4000, 2870},
        {5248, 3230},
        {8848, 3599},//这里不要3600，因为3600和0一样
};

//====================仅内部调用===================
// 创建左侧指针的角度动画回调函数
static void set_angle_left(void * img, int32_t angle)
{
    lv_img_set_angle(img, (int16_t)angle); // 设置左侧指针的旋转角度
}
// 创建右侧指针的角度动画回调函数
static void set_angle_right(void * img, int32_t angle)
{
    lv_img_set_angle(img, (int16_t)angle); // 设置右侧指针的旋转角度
}

// 设置左侧指针的动画
// 2024-09-12 第一次测试到的值，对应关系
// 60->0--
// 90->20
// 135->45
// 180->80
// 210->100--
// 225->120
// 240->140
// 270->180--
// 285->200
// 300->220--
static void set_left_pointer_angle(int16_t target_angle)
{
    // 获取当前角度
    now_angle_left = lv_img_get_angle(img_pointer_left);

    // 获取期望角度
    desire_angle_left = target_angle;

    // 设置动画时间，根据角度差值计算时间
    int32_t animation_time = abs(desire_angle_left - now_angle_left) / 10;

    // 如果当前角度已经有动画，在设置新动画之前删除旧动画
    lv_anim_del(img_pointer_left, set_angle_left);

    lv_anim_t a_left;
    lv_anim_init(&a_left);
    lv_anim_set_var(&a_left, img_pointer_left); // 左侧指针的对象
    lv_anim_set_exec_cb(&a_left, set_angle_left); // 设置角度回调函数
    lv_anim_set_values(&a_left, lv_img_get_angle(img_pointer_left), desire_angle_left); // 从当前角度到目标角度
    lv_anim_set_time(&a_left, animation_time); // 动画持续时间 animation_time 毫秒
    lv_anim_set_path_cb(&a_left, lv_anim_path_linear); // 线性路径
    lv_anim_start(&a_left);
}

// 设置右侧指针的动画
// 2024-09-12 第一次测试到的值，对应关系
// 35->0---
// 110->1000----
// 250->3000----
// 285->4000----
// 325->5248----
// 359->8848----
static void set_right_pointer_angle(int16_t target_angle)
{
    // 获取当前角度
    now_angle_right = lv_img_get_angle(img_pointer_right);

    // 获取期望角度
    desire_angle_right = target_angle;

    // 设置动画时间，根据角度差值计算时间
    int32_t animation_time = abs(desire_angle_right - now_angle_right) / 10;

    // 如果当前角度已经有动画，在设置新动画之前删除旧动画
    lv_anim_del(img_pointer_right, set_angle_right);

    lv_anim_t a_right;
    lv_anim_init(&a_right);
    lv_anim_set_var(&a_right, img_pointer_right); // 右侧指针的对象
    lv_anim_set_exec_cb(&a_right, set_angle_right); // 设置角度回调函数
    lv_anim_set_values(&a_right, lv_img_get_angle(img_pointer_right), desire_angle_right); // 从当前角度到目标角度
    lv_anim_set_time(&a_right, animation_time); // 动画持续时间 animation_time 毫秒
    lv_anim_set_path_cb(&a_right, lv_anim_path_linear); // 线性路径
    lv_anim_start(&a_right);
}
// 线性插值函数
static float linear_interpolation(int x0, int y0, int x1, int y1, int x) {
    return y0 + (float)(y1 - y0) * (x - x0) / (x1 - x0);
}

// 非线性映射函数，使用可变长度的二维数组
static float map_altitude_to_angle(int altitude, int mapping_points[][2], int num_points) {
    // 如果输入值小于最小值或大于最大值，返回边界值
    if (altitude <= mapping_points[0][0]) return mapping_points[0][1];
    if (altitude >= mapping_points[num_points - 1][0]) return mapping_points[num_points - 1][1];

    // 查找在哪两个点之间插值
    for (int i = 0; i < num_points - 1; i++) {
        if (altitude >= mapping_points[i][0] && altitude <= mapping_points[i + 1][0]) {
            // 使用线性插值计算对应的角度
            return linear_interpolation(
                    mapping_points[i][0], mapping_points[i][1],
                    mapping_points[i + 1][0], mapping_points[i + 1][1],
                    altitude
            );
        }
    }

    // 如果输入值不在范围内，返回0
    return 0;
}

//====================外部可调用===================
// 切换到第一个背景图像
void switch_to_background1(void)
{
    lv_obj_clear_flag(img_background1, LV_OBJ_FLAG_HIDDEN); // 显示第一张背景图像
    lv_obj_add_flag(img_background2, LV_OBJ_FLAG_HIDDEN); // 隐藏第二张背景图像
}

// 切换到第二个背景图像
void switch_to_background2(void)
{
    lv_obj_clear_flag(img_background2, LV_OBJ_FLAG_HIDDEN); // 显示第二张背景图像
    lv_obj_add_flag(img_background1, LV_OBJ_FLAG_HIDDEN); // 隐藏第一张背景图像
}

// 更新日期
void lv_set_date(const char * new_text)
{
    if (obj_date != NULL) {
        lv_label_set_text(obj_date, new_text);
    }
}
// 更新电话号码
void lv_set_phone_number(const char * new_text)
{
    if (obj_date != NULL) {
        lv_label_set_text(obj_phone_number, new_text);
    }
}

// 0 - 220
// 设置速度
void lv_set_speed(int speed)
{
#if DEBUG_ANGL
    set_left_pointer_angle(speed);
#else
    int num_points = sizeof(mapping_points_speed) / sizeof(mapping_points_speed[0]); // 计算点的数量
    int16_t mapped_angle = map_altitude_to_angle(speed, mapping_points_speed, num_points);
    set_left_pointer_angle(mapped_angle);
#endif
}

// 0 - 8848
// 设置海拔
void lv_set_asl(int asl)
{
#if DEBUG_ANGL
    set_right_pointer_angle(asl);
#else
    int num_points = sizeof(mapping_points_asl) / sizeof(mapping_points_asl[0]); // 计算点的数量
    int16_t mapped_angle = map_altitude_to_angle(asl, mapping_points_asl, num_points);
    set_right_pointer_angle(mapped_angle);
#endif
}


//======================lvgl初始化===========================
// 开机初始化
void lv_gui_start(void)
{
    // 创建第一个背景图像对象
    img_background1 = lv_img_create(lv_scr_act());
    lv_img_set_src(img_background1, &background);
    lv_obj_align(img_background1, LV_ALIGN_CENTER, 0, 0);

    // 创建第二个背景图像对象，但默认隐藏
    img_background2 = lv_obj_create(lv_scr_act());
    lv_obj_set_style_bg_color(img_background2, lv_color_black(), 0);// 设置对象的背景颜色为黑色
    lv_obj_set_size(img_background2, 480, 222);  // 设置对象的宽度为480，高度为222
    lv_obj_set_style_radius(img_background2, 0, 0);// 去掉圆角
    lv_obj_align(img_background2, LV_ALIGN_CENTER, 0, 0);  // 将对象居中
    lv_obj_add_flag(img_background2, LV_OBJ_FLAG_HIDDEN); // 隐藏第二张背景图像

//    /* 第二个背景图像的电话界面 */
//    img_phone = lv_img_create(img_background2);
//    lv_img_set_src(img_phone, &phone);
//    lv_obj_align(img_phone, LV_ALIGN_CENTER, 0, 0);

//    /* 电话号 */
//    obj_phone_number = lv_label_create(img_phone); /*  创建一个标签对象 */
//    lv_label_set_text(obj_phone_number, "+8614928599932"); /* 设置标签文本 */
//    lv_obj_set_style_text_font(obj_phone_number, fontmin, LV_PART_MAIN); /* 设置标签文本字体 */
//    lv_obj_set_style_text_opa(obj_phone_number, LV_OPA_COVER, LV_PART_MAIN); /* 设置标签文本透明度 */
//    lv_obj_set_style_text_color(obj_phone_number, lv_color_hex(0x828181), LV_PART_MAIN);      /* 设置标签文本颜色 */
//    lv_obj_align(obj_phone_number, LV_ALIGN_CENTER, 0, 15);/* 设置标签位置 */

    /* 创建日期显示标签 */
    obj_date = lv_label_create(img_background1); /*  创建一个标签对象 */
    lv_label_set_text(obj_date, "2024-09-10"); /* 设置标签文本 */
    lv_obj_set_style_text_font(obj_date, font, LV_PART_MAIN); /* 设置标签文本字体 */
    lv_obj_set_style_text_opa(obj_date, LV_OPA_COVER, LV_PART_MAIN); /* 设置标签文本透明度 */
    lv_obj_set_style_text_color(obj_date, lv_color_hex(0xffffff), LV_PART_MAIN);      /* 设置标签文本颜色 */
    lv_obj_align(obj_date, LV_ALIGN_TOP_LEFT, 20, 0);/* 设置标签位置 */

    /* 表盘 */
    img_disc = lv_img_create(img_background1);
    lv_img_set_src(img_disc, &disc);
    lv_obj_align(img_disc, LV_ALIGN_CENTER, 0, 0);

    /* 电池 */
    img_power = lv_img_create(img_background1);
    lv_img_set_src(img_power, &Battery);
    lv_obj_align(img_power, LV_ALIGN_CENTER, 220-10, -100);

    /* wifi图标 */
    img_wifi2 = lv_img_create(img_background1);
    lv_img_set_src(img_wifi2, &wifi2);
    lv_obj_align(img_wifi2, LV_ALIGN_CENTER, 0, 0);

    /* 左侧指针 */
    img_pointer_left = lv_img_create(img_disc);
    lv_img_set_src(img_pointer_left, &pointer2);
    lv_obj_align(img_pointer_left, LV_ALIGN_CENTER, -136, -7);
    lv_img_set_pivot(img_pointer_left, 73, 74); // 设置旋转中心点
    lv_img_set_angle(img_pointer_left, now_angle_left);

    /* 右侧指针 */
    img_pointer_right = lv_img_create(img_disc);
    lv_img_set_src(img_pointer_right, &pointer1);
    lv_obj_align(img_pointer_right, LV_ALIGN_CENTER, 134, -7);
    lv_img_set_pivot(img_pointer_right, 149/2, 149/2); // 设置旋转中心点
    lv_img_set_angle(img_pointer_right, now_angle_right);

//    /* 辅助线 */
//    static lv_point_t straigh_line_points[] = {{0,0},{480,0}};      /* 直线坐标数组 */
//    lv_obj_t *straigh_line = lv_line_create(img_background1);                                  /* 创建线条 */
//    lv_line_set_points(straigh_line, straigh_line_points, 2);                               /* 设置线条坐标点 */
//    lv_obj_align(straigh_line, LV_ALIGN_CENTER, 0, -7);      /* 设置位置 */
//
//    /* 辅助线 */
//    static lv_point_t straigh_line_points1[] = {{0,0},{0,220}};      /* 直线坐标数组 */
//    lv_obj_t *straigh_line1 = lv_line_create(img_background1);                                  /* 创建线条 */
//    lv_line_set_points(straigh_line1, straigh_line_points1, 2);                               /* 设置线条坐标点 */
//    lv_obj_align(straigh_line1, LV_ALIGN_CENTER, -136, 0);      /* 设置位置 */
//
//    /* 辅助线 */
//    static lv_point_t straigh_line_points2[] = {{0,0},{0,220}};      /* 直线坐标数组 */
//    lv_obj_t *straigh_line2 = lv_line_create(img_background1);                                  /* 创建线条 */
//    lv_line_set_points(straigh_line2, straigh_line_points2, 2);                               /* 设置线条坐标点 */
//    lv_obj_align(straigh_line2, LV_ALIGN_CENTER, 134, 0);      /* 设置位置 */
}
void my_gui(void)
{
    lv_gui_start();
}
#endif